package com.ruoyi.project.knowledge.service;

import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.project.fusion.domain.*;
import com.ruoyi.project.fusion.mapper.DataFusionMapper;
import com.ruoyi.project.fusion.service.DataFusionService;
import com.ruoyi.project.knowledge.algorithms.DataOptimizationAlgorithm;
import com.ruoyi.project.knowledge.domain.OverallAggScores;
import com.ruoyi.project.knowledge.domain.OverallScores;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DataOptimizationService {
    @Autowired
    private DataFusionService dataFusionService;
    @Autowired
    private DataFusionMapper dataFusionMapper;
    public void insertOverallScores(String chainType, String scenario, int priorityType) {
        List<HumanResourceScores> humanResourceScores = dataFusionService.getHumanResourceScores(chainType, scenario);
        List<BusinessStatusScores> businessStatusScores = dataFusionService.getBusinessStatusScores(chainType, scenario);
        List<MaterialManagementScores> materialManagementScores = dataFusionService.getMaterialManagementScores(chainType, scenario);
        List<QualityScores> qualityScores = dataFusionService.getQualityScores(chainType, scenario);
        List<PriceScores> priceScores = dataFusionService.getPriceScores(chainType, scenario);
        List<ServiceScores> serviceScores = dataFusionService.getServiceScores(chainType, scenario);
        List<TechnologyScores> technologyScores = dataFusionService.getTechnologyScores(chainType, scenario);
        List<OverallAggScores> overallAggScores = mergeData(humanResourceScores, businessStatusScores, materialManagementScores, qualityScores, priceScores, serviceScores, technologyScores);

        List<OverallScores> list = new DataOptimizationAlgorithm().compute(overallAggScores, priorityType);

        int batchSize = 1000; // 每批插入的数量，可根据数据库性能调整
        for (int i = 0; i < list.size(); i += batchSize) {
            int end = Math.min(i + batchSize, list.size());
            List<OverallScores> batchList = list.subList(i, end);
            dataFusionMapper.insertOverAllScore(batchList);
        }
    }
    public List<OverallScores> getOverallScores(String chainType, String scenario, int priorityType) {
//        List<HumanResourceScores> humanResourceScores = dataFusionService.getHumanResourceScores(chainType, scenario);
//        List<BusinessStatusScores> businessStatusScores = dataFusionService.getBusinessStatusScores(chainType, scenario);
//        List<MaterialManagementScores> materialManagementScores = dataFusionService.getMaterialManagementScores(chainType, scenario);
//        List<QualityScores> qualityScores = dataFusionService.getQualityScores(chainType, scenario);
//        List<PriceScores> priceScores = dataFusionService.getPriceScores(chainType, scenario);
//        List<ServiceScores> serviceScores = dataFusionService.getServiceScores(chainType, scenario);
//        List<TechnologyScores> technologyScores = dataFusionService.getTechnologyScores(chainType, scenario);
//        List<OverallAggScores> overallAggScores = mergeData(humanResourceScores, businessStatusScores, materialManagementScores, qualityScores, priceScores, serviceScores, technologyScores);
//
//        return new DataOptimizationAlgorithm().compute(overallAggScores, priorityType);
        List<OverallScores> allResults = new ArrayList<>();
        int pageSize = 1000;  // 每次查询的条数，可根据实际情况调整
        int offset = 0;

        List<OverallScores> batchResults;
        do {
            batchResults = dataFusionMapper.getOverAllScore(chainType, scenario,offset,pageSize);
            allResults.addAll(batchResults);
            offset += pageSize; // 移动查询起始点
        } while (!batchResults.isEmpty()); // 直到查询不到数据，说明所有数据已获取完

        return allResults;
    }



    public List<OverallAggScores> mergeData(List<HumanResourceScores> humanResourceScores, List<BusinessStatusScores> businessStatusScores, List<MaterialManagementScores> materialManagementScores, List<QualityScores> qualityScores, List<PriceScores> priceScores, List<ServiceScores> serviceScores, List<TechnologyScores> technologyScores) {
        Map<String, OverallAggScores> overallScoreAggMap = new HashMap<>();
        initForHumanResourceScores(overallScoreAggMap, humanResourceScores);
        initForBusinessStatusScores(overallScoreAggMap, businessStatusScores);
        initForMaterialManagementScores(overallScoreAggMap, materialManagementScores);
        initForQualityScores(overallScoreAggMap, qualityScores);
        initForPriceScores(overallScoreAggMap, priceScores);
        initForServiceScores(overallScoreAggMap, serviceScores);
        initForTechnologyScores(overallScoreAggMap, technologyScores);

        updateForHumanResourceScores(overallScoreAggMap, humanResourceScores);
        updateForBusinessStatusScores(overallScoreAggMap, businessStatusScores);
        updateForMaterialManagementScores(overallScoreAggMap, materialManagementScores);
        updateForQualityScores(overallScoreAggMap, qualityScores);
        updateForPriceScores(overallScoreAggMap, priceScores);
        updateForServiceScores(overallScoreAggMap, serviceScores);
        updateForTechnologyScores(overallScoreAggMap, technologyScores);
        return new ArrayList<>(overallScoreAggMap.values());
    }

    private void initForHumanResourceScores(Map<String, OverallAggScores> overallScoreAggMap, List<HumanResourceScores> humanResourceScores) {
        for (HumanResourceScores scores : humanResourceScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            overallScoreAggMap.putIfAbsent(key, new OverallAggScores(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent(), 0, 0, 0, 0, 0, 0, 0));
        }
    }

    private void initForBusinessStatusScores(Map<String, OverallAggScores> overallScoreAggMap, List<BusinessStatusScores> businessStatusScores) {
        for (BusinessStatusScores scores : businessStatusScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            overallScoreAggMap.putIfAbsent(key, new OverallAggScores(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent(), 0, 0, 0, 0, 0, 0, 0));
        }
    }

    private void initForMaterialManagementScores(Map<String, OverallAggScores> overallScoreAggMap, List<MaterialManagementScores> materialManagementScores) {
        for (MaterialManagementScores scores : materialManagementScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            overallScoreAggMap.putIfAbsent(key, new OverallAggScores(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent(), 0, 0, 0, 0, 0, 0, 0));
        }
    }

    private void initForQualityScores(Map<String, OverallAggScores> overallScoreAggMap, List<QualityScores> qualityScores) {
        for (QualityScores scores : qualityScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            overallScoreAggMap.putIfAbsent(key, new OverallAggScores(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent(), 0, 0, 0, 0, 0, 0, 0));
        }
    }

    private void initForPriceScores(Map<String, OverallAggScores> overallScoreAggMap, List<PriceScores> priceScores) {
        for (PriceScores scores : priceScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            overallScoreAggMap.putIfAbsent(key, new OverallAggScores(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent(), 0, 0, 0, 0, 0, 0, 0));
        }
    }

    private void initForServiceScores(Map<String, OverallAggScores> overallScoreAggMap, List<ServiceScores> serviceScores) {
        for (ServiceScores scores : serviceScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            overallScoreAggMap.putIfAbsent(key, new OverallAggScores(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent(), 0, 0, 0, 0, 0, 0, 0));
        }
    }

    private void initForTechnologyScores(Map<String, OverallAggScores> overallScoreAggMap, List<TechnologyScores> technologyScores) {
        for (TechnologyScores scores : technologyScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            overallScoreAggMap.putIfAbsent(key, new OverallAggScores(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent(), 0, 0, 0, 0, 0, 0, 0));
        }
    }

    private void updateForHumanResourceScores(Map<String, OverallAggScores> overallScoreAggMap, List<HumanResourceScores> humanResourceScores) {
        for (HumanResourceScores scores : humanResourceScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            OverallAggScores overallAggScores = overallScoreAggMap.get(key);
            overallAggScores.setHumanResourceScores(scores.getScore());
        }
    }

    private void updateForBusinessStatusScores(Map<String, OverallAggScores> overallScoreAggMap, List<BusinessStatusScores> businessStatusScores) {
        for (BusinessStatusScores scores : businessStatusScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            OverallAggScores overallAggScores = overallScoreAggMap.get(key);
            overallAggScores.setBusinessStatusScores(scores.getScore());
        }
    }

    private void updateForMaterialManagementScores(Map<String, OverallAggScores> overallScoreAggMap, List<MaterialManagementScores> materialManagementScores) {
        for (MaterialManagementScores scores : materialManagementScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            OverallAggScores overallAggScores = overallScoreAggMap.get(key);
            overallAggScores.setMaterialManagementScores(scores.getScore());
        }
    }

    private void updateForQualityScores(Map<String, OverallAggScores> overallScoreAggMap, List<QualityScores> qualityScores) {
        for (QualityScores scores : qualityScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            OverallAggScores overallAggScores = overallScoreAggMap.get(key);
            overallAggScores.setQualityScores(scores.getScore());
        }
    }

    private void updateForPriceScores(Map<String, OverallAggScores> overallScoreAggMap, List<PriceScores> priceScores) {
        for (PriceScores scores : priceScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            OverallAggScores overallAggScores = overallScoreAggMap.get(key);
            overallAggScores.setPriceScores(scores.getScore());
        }
    }

    private void updateForServiceScores(Map<String, OverallAggScores> overallScoreAggMap, List<ServiceScores> serviceScores) {
        for (ServiceScores scores : serviceScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            OverallAggScores overallAggScores = overallScoreAggMap.get(key);
            overallAggScores.setServiceScores(scores.getScore());
        }
    }

    private void updateForTechnologyScores(Map<String, OverallAggScores> overallScoreAggMap, List<TechnologyScores> technologyScores) {
        for (TechnologyScores scores : technologyScores) {
            String key = generateKey(scores.getChainType(), scores.getEnterpriseName(), scores.getScenario(), scores.getProduct(), scores.getEvent());
            OverallAggScores overallAggScores = overallScoreAggMap.get(key);
            overallAggScores.setTechnologyScores(scores.getScore());
        }
    }

    private String generateKey(String chainType, String enterpriseName, String scenario, String product, String event) {
        return chainType + "|" + enterpriseName + "|" + scenario + "|" + product + "|" + event;
    }
}
